package com.mysns.module.mail.service;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 邮件发送服务者
 * 
 * @author zhouych
 */
public class MailService {

	/**
	 * Spring封装的邮件发送者
	 */
	private JavaMailSender mailSender;
	
	/**
	 * 邮件的发送者
	 */
	private String sender;
	
	/**
	 * 邮件编码
	 */
	private String encoding;
	
	/**
	 * 异步线程执行器
	 */
	private TaskExecutor taskExecutor;
	
	/**
	 * 邮件的模板
	 */
	private FreeMarkerConfigurer freeMarkerConfigurer;
	
	/**
	 * 模板文件
	 */
	private String templateFile;

	public void setMailSender(JavaMailSender mailSender) {
		this.mailSender = mailSender;
	}
	
	public void setSender(String sender) {
		this.sender = sender;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public void setTaskExecutor(TaskExecutor taskExecutor) {
		this.taskExecutor = taskExecutor;
	}

	public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {
		this.freeMarkerConfigurer = freeMarkerConfigurer;
	}

	public void setTemplateFile(String templateFile) {
		this.templateFile = templateFile;
	}
	
	/**
	 * 向单个指定用户发送简单邮件
	 * 
	 * @param subject
	 *            邮件标题
	 * @param content
	 *            邮件内容
	 * @param receiver
	 *            邮件接收者
	 * @throws MessagingException
	 */
	public void sendTextMail(String subject, String content, String receiver)
			throws MessagingException {

		MimeMessage mimeMsg = mailSender.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(mimeMsg, true, encoding);
		helper.setTo(receiver);
		helper.setFrom(sender);
		helper.setSubject(subject);
		helper.setText(content, true);
		mailSender.send(mimeMsg);
	}
	
	/**
	 * 发送Html格式的邮件
	 * 
	 * @param subject
	 * @param content
	 * @param receiver
	 * @throws MessagingException
	 * @throws IOException
	 * @throws TemplateException
	 */
	public void sendHtmlMail(String subject, String receiver, String... contents)
		throws MessagingException, IOException, TemplateException {
		
		MimeMessage mimeMsg = mailSender.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(mimeMsg, true, encoding);
		helper.setTo(receiver);
		helper.setFrom(sender);
		helper.setSubject(subject);
		// 利用模板生成html邮件内容
		String htmlText = generateMailContent(contents);
		helper.setText(htmlText, true);
		mailSender.send(mimeMsg);
	}
	
	/**
	 * 发送带附件的邮件.
	 * 
	 * @param subject
	 * @param content
	 * @param receiver
	 * @param attachments
	 * @throws MessagingException
	 * @throws IOException
	 * @throws TemplateException
	 */
	public void sendAttachmentMail(String subject, String content,
			String receiver, String[] attachments)
			throws MessagingException, IOException, TemplateException {
		
		MimeMessage mimeMsg = mailSender.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(mimeMsg, true,
				encoding);
		helper.setTo(receiver);
		helper.setFrom(sender);
		helper.setSubject(subject);
		helper.setText(content);
		for (String attachment : attachments) {
			// 附件名，如：E:/logo.png
			File file = new File(attachment);
			// MimeUtility.encodeWord()方法用来解决附件的中文问题
			helper.addAttachment(MimeUtility.encodeWord(file.getName()), file);
		}
		mailSender.send(mimeMsg);
	}
	
	/**
	 * 异步发送邮件
	 */
	public void sendAsyncHtmlMail(final String subject, final String receiver,
			final String... contents) {
		
		taskExecutor.execute(new Runnable() {
			public void run() {
				try {
					sendHtmlMail(subject, receiver, contents);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	
	/**
	 * 根据 FreeMarker 生成邮件的自定义模板.
	 * 
	 * @param contents 不定长的string内容
	 * @return
	 * @throws IOException
	 * @throws TemplateException
	 */
	private String generateMailContent(String... contents) throws IOException,
			TemplateException {
		
		Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templateFile);
		Map<String, String> map = new HashMap<String, String>();
		for (int i = 1; i <= contents.length; i++) {
			map.put("content" + i, contents[i-1]);
		}
		// 解析模板并替换动态数据，比如content将替换模板文件中的${content}标签
		return FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
	}
}
